/**
 * 文件名称: maic.c
 * 摘    要: 文件传输linux客户端(命令行方式)入口代码
 * 来    源: 自我总结
 *
 * 当前版本: 1.0 
 * 作    者: huenrong
 * 完成日期: 2019-07-07
 **/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>


#include "./file_transfer/file_transfer.h"

extern struct file_info g_file_info;     // 记录上传文件信息


int main(int argc, char *argv[])
{
    int ret = -1;
    int client_fd = -1;     // 客户端socket套接字
    struct sockaddr_in server_addr;      // 服务器socket地址
    char server_ip[INET_ADDRSTRLEN] = {0};  // 服务器ip
    int server_port = 0;        // 服务器port

    if (4 != argc)
	{
		printf("usage : %s <server ip> <server port> <file name>\n", argv[0]);
		
        return -1;
	}

    // 获取输入参数信息
    memcpy(server_ip, argv[1], strlen(argv[1]));
    server_port = atoi(argv[2]);
    memcpy(g_file_info.file_name, argv[3], strlen(argv[3]));        // 获取传输文件名
    g_file_info.file_size = get_file_size(argv[3]);     // 获取传输文件大小
    
    // 如果传输文件大小是0, 则直接退出，并打印提示信息
    if (0 == g_file_info.file_size)
    {
        printf("%s file size is 0 kb\n", argv[3]);

        return -1;
    }

    // 程序启动打印日志
    printf("file_transfer_client start\n");

    // 创建TCP套接字
    // SOCK_STREAM表示使用面向连接的socket，即使用TCP连接
    client_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (client_fd < 0)
    {
        perror("socket error");

        exit(-1);
    }

    // 初始化需要连接的服务器地址
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(server_port);  ///服务器port
    server_addr.sin_addr.s_addr = inet_addr(server_ip);  ///服务器ip

    while (1)
    {
        // 打印连接信息
        printf("connecting to %s:%d ...\n", server_ip, server_port);

        // 连接指定的服务器
        ret = connect(client_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr));
        if (ret < 0)
        {
            perror("connect error");

            sleep(1);
        }

        // 打印连接成功提示信息
        printf("connect to server[%s:%d] ok\n", server_ip, server_port);

        // 设置socket为非阻塞模式
        // ret = fcntl(client_fd, F_GETFL, 0);
        // fcntl(client_fd, F_SETFL, (ret | O_NONBLOCK));

        while (1)
        {
            ret = file_transfer_client_function(client_fd);
            if (0 == ret)       // 传输成功
            {
                close(client_fd);        // 传输完成, 关闭套接字

                return 0;
            }
            else if (-1 == ret)     // 服务器关闭/socket异常情况, 重连服务器
            {
                printf("reconnect server...\n");
                
                break;
            }
            else        // 传输过程发生错误, 结束传输
            {
                close(client_fd);

                return 0;
            }
        }
    }

    return 0;
}
